<template>
  <div class="simple-table-wrap" :ref="id">
    <Table
      ref="table"
      class="table-box"
      :columns="tableColums"
      :loading="tableLoading"
      size="small"
      :data="tableList"
      :height="tableHeight"
      :no-data-text="tableHint"
      @on-row-click="handleRowClick"
      highlight-row
    />
    <div class="page-box">
      <Page
        ref="page"
        :total="total"
        size="small"
        simple
        @on-change="handleChangePage"
        :page-size="pageSize"
        :current="pageNum"
      />
      <span class="rest-btn" title="重置" @click="handleRefresh" v-show="refreshBtn">
        <Icon type="md-refresh-circle" />
      </span>
    </div>
  </div>
</template>
<script>
import { map } from 'lodash'
import { nanoid } from 'nanoid'
import setTableHeightMixin from '@/mixins/setTableHeight'

export default {
  name: 'SimpleTable',
  mixins: [setTableHeightMixin],
  props: {
    tableColums: {
      type: Array,
      require: true
    },
    tableLoading: {
      type: Boolean,
      default: false
    },
    tableData: {
      type: Object,
      require: true
    },
    tableHint: {
      type: String,
      default: '暂无数据'
    },
    pageSize: {
      type: Number,
      default: 20
    },
    pageNum: {
      type: Number,
      default: 1
    },
    keyUp: {
      type: Boolean,
      default: false
    },
    stopKeyUp: {
      type: Boolean,
      default: false
    },
    refreshBtn: {
      type: Boolean,
      default: true
    }
  },
  data() {
    return {
      tableHeight: 0,
      tableList: [],
      total: 0,
      selectedIndex: undefined
    }
  },
  watch: {
    tableData: {
      handler() {
        this.removeKeyUpEvent()
        const { list = [], total } = this.tableData
        this.tableList = list
        this.total = total
        this.selectedIndex = undefined
      }
    }
  },
  computed: {
    id() {
      return nanoid()
    }
  },
  beforeDestroy() {
    window.removeEventListener('resize', this.setTableHeight)
    this.removeKeyUpEvent()
  },
  mounted() {
    this.setTableHeight()
    window.addEventListener('resize', this.setTableHeight)
  },
  methods: {
    removeKeyUpEvent() {
      document.removeEventListener('keyup', this.handleKeyUp)
    },
    /**
     * desc: 点击重置刷新
     * param {type}
     * return {type} void
     */
    handleRefresh() {
      this.$emit('handleRefresh')
    },
    /**
     * desc: 点击分页
     * param {type}
     * return {type} void
     */
    handleChangePage(num) {
      this.$emit('handleChangePage', num)
    },
    /**
     * desc: 设置表格高度
     * param {type}
     * return {type} void
     */
    setTableHeight() {
      const _pageHeight = this.$refs.page ? this.$refs.page.$el.clientHeight : 0
      const _pHeight =
        this.$refs[this.id] && this.$refs[this.id].clientHeight
      this.tableHeight = Number(_pHeight) && Number(_pageHeight) ? _pHeight - _pageHeight : 0
    },
    /**
     * desc: 行单击事件
     * param {type}
     * return {type} void
     */
    handleRowClick(row, index) {
      this.selectedIndex = index
      this.$emit('hanleRowClick', row, index)
      if (this.keyUp) {
        this.handleBindKeyUp()
      }
    },
    handleBindKeyUp() {
      document.addEventListener('keyup', this.handleKeyUp)
    },
    handleKeyUp() {
      if (this.stopKeyUp) {
        return
      }
      switch (Number(event.keyCode)) {
        case 87: // w 表格下选择
          if (this.tableList.length < 2) return
          if (this.selectedIndex <= 0) {
            this.selectedIndex = 0
          } else {
            this.selectedIndex--
          }
          this.eventTableKeyUpAfter(Number(event.keyCode))
          break
        case 83: // s 表格上选择
          if (this.tableList.length < 2) return
          const len = this.tableList.length
          if (this.selectedIndex >= len - 1) {
            this.selectedIndex = len - 1
          } else {
            this.selectedIndex++
          }
          this.eventTableKeyUpAfter(Number(event.keyCode))
          break
        default:
          break
      }
    },
    /**
     * @msg: 按键操作完之后的操作
     * @param {type}
     * @return:
     */
    eventTableKeyUpAfter (code) {
      this.$nextTick(() => {
        this.tableList = map(this.tableList, (item, index) => {
          if (index === this.selectedIndex) {
            item._highlight = true
          } else {
            item._highlight = false
          }
          return item
        })
      })
      this.setTableScroll(code)
      const _row = this.tableList[this.selectedIndex]
      this.handleRowClick(_row, this.selectedIndex)
    },
    /**
     * @msg: 表格滚动条控制
     * @param {type}
     * @return:
     */
    setTableScroll (code) {
      if (!this.$refs.table) {
        return
      }
      const rowHeight = this.$refs.table.$el.querySelector('.ivu-table-row').offsetHeight

      const scrollTop = this.$refs.table.$el.querySelector('.ivu-table-body').scrollTop
      const tableAreaHeight = this.$refs.table.$el.querySelector('.ivu-table-body').offsetHeight

      const num = this.selectedIndex + 1
      if ((num * rowHeight + rowHeight) > tableAreaHeight && code === 83) {
        this.$refs.table.$el.querySelector('.ivu-table-body').scrollTop += rowHeight
      }

      if ((this.selectedIndex * rowHeight - rowHeight) < scrollTop && code === 87) {
        this.$refs.table.$el.querySelector('.ivu-table-body').scrollTop -= rowHeight
      }
    }
  }
}
</script>
<style lang="less" scoped>
.simple-table-wrap {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;

  .table-box {
    position: absolute;
    top: 0;
    left: 0;
    bottom: 38px;
    width: 100%;
  }

  .page-box {
    position: absolute;
    left: 0;
    bottom: 0;
    width: 100%;
    height: 38px;
    line-height: 38px;
    box-sizing: border-box;
    text-align: center;
  }

  .rest-btn {
    position: absolute;
    top: 0;
    right: 50%;
    margin-right: -115px;
    font-size: 24px;
    cursor: pointer;
  }
}
</style>
